package cn.tedu.ivos.dictoption.service.impl;

import cn.tedu.ivos.base.exception.ServiceException;
import cn.tedu.ivos.base.response.StatusCode;
import cn.tedu.ivos.base.uitls.CacheUtils;
import cn.tedu.ivos.dict.mapper.DictMapper;
import cn.tedu.ivos.dict.pojo.dto.DictQuery;
import cn.tedu.ivos.dict.pojo.dto.DictSaveParam;
import cn.tedu.ivos.dict.pojo.entity.Dict;
import cn.tedu.ivos.dict.pojo.vo.DictVO;
import cn.tedu.ivos.dictoption.mapper.DictoptionMapper;
import cn.tedu.ivos.dictoption.pojo.dto.DictOptionQuery;
import cn.tedu.ivos.dictoption.pojo.dto.DictOptionSaveParam;
import cn.tedu.ivos.dictoption.pojo.entity.DictOption;
import cn.tedu.ivos.dictoption.pojo.vo.DictOptionVO;
import cn.tedu.ivos.dictoption.service.DictoptionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class DictoptionServiceImpl implements DictoptionService {
    @Autowired
    private DictoptionMapper dictoptionMapper;
    @Autowired
    private DictMapper dictMapper;
    // 注入工具类
    @Autowired
    private CacheUtils cacheUtils;

    @Override
    public List<DictOptionVO> selectDictOption(DictOptionQuery dictOptionQuery) {
        return dictoptionMapper.selectDictOption(dictOptionQuery);
    }


    @Override
    public void saveDictOption(DictOptionSaveParam dictSaveParam) {
        DictOption dictOption = new DictOption();
        BeanUtils.copyProperties(dictSaveParam,dictOption);
        if (dictOption.getId()==null){
            dictOption.setCreateTime(new Date());
            dictoptionMapper.insert(dictOption);
        }else {
            dictoptionMapper.update(dictOption);
        }
    //     新增或者更新后,将dictOption的最新数据存入Redis中
        DictQuery dict= new DictQuery();
        dict.setId(dictOption.getId());
        List<DictVO> dictVOList = dictMapper.selectDict(dict);
        if (dictVOList!=null && dictVOList.size()>0){
            DictVO dictVO = dictVOList.get(0);
            // 根据之前的code删除之前的redis缓存数据
            cacheUtils.delete("dictOption"+dictVO.getCode());
            //封装字典项查询DTO
            DictOptionQuery dictOptionQuery = new DictOptionQuery();
            dictOptionQuery.setDictId(dictVO.getId());
            //查询对应的字典项
            List<DictOptionVO> dictOptionVOList = dictoptionMapper.selectDictOption(dictOptionQuery);
            //设置新的redis缓存
            cacheUtils.set("dictOption"+dictVO.getCode(),dictOptionVOList);

        }

    }

    // 思路就是通过dicOptionId进行封装查找,查找到对应的DictOption
    // 这个过程就是查找对应的DictOption(封装查找) 之后通过DictOption中的Dict_Id 再次进行(封装查找)到对应的DictVO
    // 之后进行删除之前的redis的key,再次设置好 KEY - VALUE 进行redis的更新操作
    @Override
    public void deleteDoctOption(Long id) {
        //只删除了数据库中的数据,会造成数据库的数据与redis数据不一致  要同时把redis也进行更新
        DictOptionQuery optionQuery = new DictOptionQuery();
        optionQuery.setId(id);
        List<DictOptionVO> optionVOList = dictoptionMapper.selectDictOption(optionQuery);
        if (optionVOList!=null && optionVOList.size()>0){
            // 如果集合不为空,则去除字典项中的数据
            DictOptionVO dictOptionVO = optionVOList.get(0);
            DictQuery dict = new DictQuery();
            dict.setId(dictOptionVO.getId());
            // 上边所有的代码都是为了通过DictOpstion的Id Id 去查找对应的Dict表单项
            List<DictVO> dictVOList = dictMapper.selectDict(dict);
            if (dictVOList!=null && dictVOList.size()>0){
                DictVO dictVO = dictVOList.get(0);
                //根据dict的Code删除之前的redis缓存
                cacheUtils.delete("dictOption"+dictVO.getId());
                //封装字典项查询DTO
                DictOptionQuery dictOptionQuery = new DictOptionQuery();
                dictOptionQuery.setDictId(dictVO.getId());
                //查询对应的字典项
                List<DictOptionVO> dictOptionVOList = dictoptionMapper.selectDictOption(dictOptionQuery);
                //设置新的redis缓存 KEY-VALUE 形式存储
                cacheUtils.set("dictOption"+dictVO.getCode(),dictOptionVOList);
            }
        }
        dictoptionMapper.deleteById(id);
    }

    @Override
    public List<DictOptionVO> selectDictOptionByCode(String code) {
        log.debug("根据字典编码查询字典项,查询的字典项={}",code);
        Object obj = cacheUtils.get("dictOption" + code);
        if (obj!=null){
            //缓存中有就直接返回缓存中的数据,避免再次查询数据库
            log.debug("从缓存中获取字典项,查询的字典项={}",code);
            // 如果在redis中回去到字典项的话,就不用再去数据库查询了
            return (List<DictOptionVO>) obj;
        }
        log.debug("从缓存中没有获取到字典项,查询的字典项={}",code);
        // 把接收到的数据 封装字典查询DTO
        DictQuery dictQuery = new DictQuery();
        dictQuery.setCode(code);
        // 查询对应的表字段
        List<DictVO> dictVOList = dictMapper.selectDict(dictQuery);
        if (dictVOList!=null && dictVOList.size()>0){ //dictVoList可能是null也可能为0
            DictVO dictVO = dictVOList.get(0);
            DictOptionQuery dictOptionQuery = new DictOptionQuery();
            dictOptionQuery.setDictId(dictVO.getId());
            List<DictOptionVO> dictOptionVOList = selectDictOption(dictOptionQuery);
            log.debug("从数据库中获取到字典项,查询的字典项={}",code);
            //从数据库中获取到字典项信息,则保存到redis缓存中
            cacheUtils.set("dictOption"+code,dictOptionVOList);
            log.debug("将字典项设置到缓存,查询的字典项={}",code);
            return dictOptionVOList;
        }else{
        //     如果找不到对应的字典字段,则抛出业务层异常数据不存在
            throw new ServiceException(StatusCode.DATA_UNEXISTS);
        }
    }


}
